#pragma once


#include <QtGlobal>
#include <QRectF>
#include <QPainterPath>

#include "LeGraphics.h"
#include "LeGraphicsPalette.h"

class GraphicsStyleOption;

class LEGRAPHICSVIEW_EXPORT LeGraphicsStyle: public QObject
{
    Q_OBJECT

public:
    explicit LeGraphicsStyle(QObject *parent = nullptr);
    virtual ~LeGraphicsStyle();

    enum StateFlag
    {
        // By order of precedence:
        Edited = 0x01,
        Highlighted = 0x02,
        Selected = 0x04,

        // Exclusive
        MarkedGood = 0x10,
        MarkedBad = 0x20,

        NoStateFlag = 0x00
    };
    Q_DECLARE_FLAGS(State, StateFlag)

    void drawCircle(const GraphicsStyleOption *option, QPainter *painter,
                    const QPointF &center, qreal diameter);

    void drawRect(const GraphicsStyleOption *option, QPainter *painter,
                  const QRectF &rect);

    void fillPath(const GraphicsStyleOption *option, QPainter *painter,
                  const QPainterPath &path);

    void drawOrigin(const GraphicsStyleOption *option, QPainter *painter,
                    const QPointF &pos);

    void drawCursor(const GraphicsStyleOption *option, QPainter *painter,
                    const QPointF &pos);

    void drawMajorGrid(const GraphicsStyleOption *option, QPainter *painter,
                       const QVector<qreal> &xValues, const QVector<qreal> &yValues,
                       const QPointF &topLeft, const QPointF &bottomRight);

    void drawMinorGrid(const GraphicsStyleOption *option, QPainter *painter,
                       const QVector<qreal> &xValues, const QVector<qreal> &yValues,
                       const QPointF &topLeft, const QPointF &bottomRight);

    QRectF handleBoundingRect(LeGraphicsHandleRole role) const;
    void drawHandle(const GraphicsStyleOption *option, QPainter *painter,
                    LeGraphicsHandleRole role, qreal rotation = 0.0);

    void strokePath(const GraphicsStyleOption *option, QPainter *painter,
                    const QPainterPath &path, const QPainterPath &shape,
                    qreal width);

    void drawRubberBand(const GraphicsStyleOption *option, QPainter *painter,
                        const QRectF &rect);

    void drawZoomInBox(const GraphicsStyleOption *option, QPainter *painter,
                       const QRectF &rect);

    void drawZoomOutBox(const GraphicsStyleOption *option, QPainter *painter,
                        const QRectF &rect);

    QString formatFeatureMetaData(const QMap<QString, QString> metadata);

private:
    Q_DISABLE_COPY(LeGraphicsStyle)
    static QColor alphaBlend(const QColor &source, const QColor &dest, qreal alpha);
    static QPen fillFeaturePen(const GraphicsStyleOption *option, const QBrush &brush);
    static QBrush fillFeatureBrush(const GraphicsStyleOption *option, const QPainter *painter);
};

Q_DECLARE_OPERATORS_FOR_FLAGS(LeGraphicsStyle::State)

class LEGRAPHICSVIEW_EXPORT GraphicsStyleOption
{
public:
    GraphicsStyleOption(): state(0) {}
    GraphicsStyleOption(const GraphicsStyleOption &other)
    { *this = other; }

    LeGraphicsPalette palette;
    LeGraphicsStyle::State state;
    QRectF exposedRect;
};
